package org.an.proj.contacts.ui.base;

import android.annotation.SuppressLint;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.webkit.CookieManager;
import android.webkit.DownloadListener;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import java.io.InputStream;
import org.an.ku.view.MyHorizontalProgressBar;
import org.an.proj.contacts.R;
import org.an.proj.contacts.config.Config;
import org.an.proj.contacts.config.LogUtil;

/**
 * Created by Fcy on 2016/4/25.
 */
public abstract class BaseWebViewActivity extends BaseActivity {
  protected static final String TAG = Config.TAG_WEBVIEW;
  private static final int MAX = 100;
  protected WebView mWebView;
  protected String mCurrentUrl;
  protected MyHorizontalProgressBar mProgressBar;

  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView();
    mWebView = (WebView) findViewById(R.id.webView);
    mProgressBar = (MyHorizontalProgressBar) findViewById(R.id.progressBar);
    mProgressBar.setMaxValue(MAX);
    mCurrentUrl = initCurrUrl();
    setUpWebView();
    reload();
  }

  protected abstract String initCurrUrl();

  protected abstract void setContentView();

  protected WebView getWebView() {
    return mWebView;
  }

  protected String getCurrentUrl() {
    return mCurrentUrl;
  }

  /**
   * 加载当前url
   */
  protected void reload() {
    load(mCurrentUrl);
  }

  protected void load(String url) {
    mWebView.loadUrl(url);
    LogUtil.d(TAG, "url:" + url);
  }

  protected void registerJS() {
  }

  @SuppressLint("JavascriptInterface")
  protected void addJavascriptInterface(Object object, String name) {
    mWebView.addJavascriptInterface(object, name);
  }

  /**
   * 处理非 http或https
   *
   * @param url url shouldOverrideUrlLoading
   * @return True if the host application wants to leave the current WebView
   * and handle the url itself, otherwise return false.
   */
  protected boolean shouldOverrideUrlLoading(WebView view, String url) {
    return true;
  }

  /**
   *
   * @param view
   * @param url
   * @param isSuccess
   */
  protected void onPageFinished(WebView view, String url, boolean isSuccess) {
  }

  @SuppressLint("SetJavaScriptEnabled") private void setUpWebView() {
    mWebView.setVerticalScrollBarEnabled(true);
    mWebView.setHorizontalScrollBarEnabled(false);
    mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
    // mWebView.setInitialScale(1);
    mWebView.setWebViewClient(initWebViewClient());
    mWebView.setWebChromeClient(initWebChromeClient());
    mWebView.setDownloadListener(new DownloadListener() {
      @Override public void onDownloadStart(String url, String userAgent, String contentDisposition,
          String mimetype, long contentLength) {
        //mIntentFactory.goToWeb(url);
      }
    });

    WebSettings settings = mWebView.getSettings();
    settings.setUseWideViewPort(true);
    settings.setDomStorageEnabled(true);
    settings.setJavaScriptEnabled(true);
    // 设置可以支持缩放
    settings.setSupportZoom(true);
    // 设置出现缩放工具
    settings.setBuiltInZoomControls(false);
    // 扩大比例的缩放
    settings.setUseWideViewPort(true);
    // 自适应屏幕
    settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
    settings.setLoadWithOverviewMode(true);
    settings.setLoadsImagesAutomatically(true);
    // 设置UA
    //settings.setUserAgentString(mWebView.getSettings().getUserAgentString()
    //    + "/jaaksi/contact/"
    //    + BuildConfig.VERSION_NAME);
    // mWebView.setInitialScale(70);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      //在安卓5.0之后，默认不允许加载http与https混合内容，需要设置webview允许其加载混合网络协议内容
      settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
      //设置运行跨域读取cookie
      CookieManager.getInstance().setAcceptThirdPartyCookies(mWebView, true);
    }
    registerJS();
  }

  protected WebViewClient initWebViewClient() {
    return new MyWebViewClient();
  }

  /**
   * 如果要自己定义，必须调用下面方法
   * mProgressBar.setProgress(newProgress);
   */
  protected WebChromeClient initWebChromeClient() {
    return new WebChromeClient() { // 处理进度
      public void onProgressChanged(WebView view, int newProgress) {
        BaseWebViewActivity.this.onProgressChanged(view, newProgress);
      }
    };
  }

  /**
   * 更新进度
   *
   * @param newProgress 0-100
   */
  protected void onProgressChanged(WebView view, int newProgress) {
    LogUtil.d(TAG, "progress:" + newProgress);
    mProgressBar.setProgress(newProgress);
    //float progress = newProgress * 1.f / mProgressBar.getMaxValue();
    //mProgressBar.setProgress(progress);
  }

  @Override public void onClickBack() {
    goBack();
  }

  @Override public void onBackPressed() {
    goBack();
  }

  protected void goBack() {
    if (mWebView.canGoBack()) {
      mWebView.goBack();
    } else {
      super.onBackPressed();
    }
  }

  protected class MyWebViewClient extends WebViewClient {
    private boolean isSuccess;

    public boolean shouldOverrideUrlLoading(WebView view, String url) { // h5中跳转，会调用这个方法,url会改变
      if (url.startsWith("http:") || url.startsWith("https:")) {
        mCurrentUrl = url;
        LogUtil.i(TAG, "OverrideUrl:" + url);
        return false;
      }

      return BaseWebViewActivity.this.shouldOverrideUrlLoading(view, url);
    }

    /**
     * 通知主程序页面当前开始加载。该方法只有在加载main frame时加载一次，
     * 如果一个页面有多个frame，onPageStarted只在加载main frame时调用一次。
     * 也意味着若内置frame发生变化，onPageStarted不会被调用，如：在iframe中打开url链接。
     */
    @Override public void onPageStarted(WebView view, String url, Bitmap favicon) {
      isSuccess = true;
      mProgressBar.setVisibility(View.VISIBLE);
    }

    @Override public void onPageFinished(WebView view, String url) {
      mProgressBar.setVisibility(View.GONE);
      LogUtil.e(TAG, "onPageFinished");
      //mHandler.postDelayed(new Runnable() {
      //  @Override public void run() {
      //    mProgressBar.setVisibility(View.GONE);
      //  }
      //}, 200);
      // 如果发生 onReceivedError,则回调onPageFinished progress=0
      BaseWebViewActivity.this.onPageFinished(view, url, isSuccess);
    }

    @Override public void onReceivedError(WebView view, int errorCode, String description,
        String failingUrl) {
      isSuccess = false;
      LogUtil.d(TAG, "onReceivedError:" + failingUrl);
    }

    /**
     * 当出现SSL错误时，WebView默认是取消加载当前页面，只有去掉onReceivedSslError的默认操作，
     * 然后添加SslErrorHandler.proceed()才能继续加载出错页面
     * 当HTTPS传输出现SSL错误时，错误会只通过onReceivedSslError回调传过来
     */
    @Override public void onReceivedSslError(WebView view, SslErrorHandler handler,
        SslError error) {
      //super.onReceivedSslError(view, handler, error);
      handler.proceed();
      LogUtil.d(TAG, "onReceivedSslError:" + error.getUrl());
    }

    /**
     * 在每一次请求资源时，都会通过这个函数来回调，比如超链接、JS文件、CSS文件、图片等，
     * 也就是说浏览器中每一次请求资源时，都会回调回来，无论任何资源！
     * 但是必须注意的是shouldInterceptRequest函数是在非UI线程中执行的，在其中不能直接做UI操作
     *
     * 该函数会在请求资源前调用，我们可以通过返回WebResourceResponse的处理结果来让WebView直接使用我们的处理结果。
     * 如果我们不想处理，则直接返回null，系统会继续加载该资源。
     * 利用这个特性，我们可以解决一个需求：假如网页中需要加载本地的图片，
     * 我们就可以通过拦截shouldInterceptRequest，并返回结果即可
     */
    @Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
      LogUtil.d(TAG, "shouldInterceptRequest:url=" + url);
      try {
        if (url.equals("http://localhost/qijian.png")) {
          // 根据字符串找文件
          AssetFileDescriptor fileDescriptor = getAssets().openFd("s07.jpg");
          InputStream stream = fileDescriptor.createInputStream();
          WebResourceResponse response = new WebResourceResponse("image/png", "UTF-8", stream);
          return response;
        }
      } catch (Exception e) {
      }
      return super.shouldInterceptRequest(view, url);
    }
  }
}
